package com.tanhua.manage.service;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tanhua.manage.domain.AnalysisByDay;
import com.tanhua.manage.mapper.AnalysisByDayMapper;
import com.tanhua.manage.mapper.LogMapper;
import com.tanhua.manage.utils.ComputeUtil;
import com.tanhua.manage.vo.AnalysisSummaryVo;
import com.tanhua.manage.vo.SummaryVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class AnalysisByDayService extends ServiceImpl<AnalysisByDayMapper, AnalysisByDay> {


    @Autowired(required = false)
    private AnalysisByDayMapper analysisByDayMapper;

    @Autowired(required = false)
    private LogMapper logMapper;


    /**
     * 统计概要信息
     * 2021-08-17：改，每天查询数据前，先更新数据
     * @return
     */
    public ResponseEntity summary() {
        //1. 得到今日与昨天的日期
        Date nowDate = new Date();
        String now = DateUtil.formatDate(nowDate);//默认日期格式： yyyy-MM-dd
        String yesterday = ComputeUtil.offsetDay(nowDate, -1);
        //返回数据--改
        AnalysisSummaryVo vo = new AnalysisSummaryVo();
        //--改--：每天查询前，先更新数据
        this.anasysis();
        //2. 查询累计用户数
        AnalysisByDay analysisByDay = query().select("SUM(num_registered) numRegistered").one();
        Integer numRegistered = analysisByDay.getNumRegistered();
        //3. 查询新增用户、登陆次数、活跃用户（今日、昨天）
        AnalysisByDay todayAnalysisByDay = query().eq("record_date", now).one();
        AnalysisByDay yesterdayAnalysisByDay = query().eq("record_date", yesterday).one();
        Integer todayNumRegistered = todayAnalysisByDay.getNumRegistered();
        Integer todayNumLogin = todayAnalysisByDay.getNumLogin();
        Integer todayNumActive = todayAnalysisByDay.getNumActive();



        //昨天--改
        Integer yesNumRegistered = 0;
        Integer yesNumLogin = 0;
        Integer yesNumActive = 0;
        if (yesterdayAnalysisByDay!=null) {
            yesNumRegistered = yesterdayAnalysisByDay.getNumRegistered();
            yesNumLogin = yesterdayAnalysisByDay.getNumLogin();
            yesNumActive = yesterdayAnalysisByDay.getNumActive();
        }


        vo.setNewUsersToday(todayNumRegistered.longValue()); //今日新增用户
        vo.setNewUsersTodayRate(ComputeUtil.computeRate(todayNumRegistered, yesNumRegistered));
        vo.setLoginTimesToday(todayNumLogin.longValue()); //今日登陆次数
        vo.setLoginTimesTodayRate(ComputeUtil.computeRate(todayNumLogin, yesNumLogin));
        vo.setActiveUsersToday(todayNumActive.longValue()); //今日活跃用户数
        vo.setActiveUsersTodayRate(ComputeUtil.computeRate(todayNumActive, yesNumActive));


        //4. 查询7天与30天活跃用户数
        Long day7 = this.getBaseMapper().findNumActiveByDate(ComputeUtil.offsetDay(nowDate, -7), nowDate);
        //5. 创建vo，把数据封装到vo中
        Long day30 = this.getBaseMapper().findNumActiveByDate(ComputeUtil.offsetDay(nowDate, -30), nowDate);
        //6 .返回响应

        vo.setCumulativeUsers(numRegistered.longValue()); //累计用户
        vo.setActivePassMonth(day30);//过去30天活跃用户u
        vo.setActivePassWeek(day7);//过去7天活跃用户u


        return ResponseEntity.ok(vo);
    }

    /**
     * 分析日志表把结果数据更新到日表中
     */
    public void anasysis() {
        //1. 查询日表有没有当前的记录
        String now = DateUtil.formatDate(new Date());
        String yesterday = ComputeUtil.offsetDay(new Date(), -1);
        AnalysisByDay analysisByDay = query().eq("record_date", now).one();
        //2. 如果当前还没有记录，那么插入一个新记录，当天
        if (analysisByDay == null) {
            analysisByDay = new AnalysisByDay();
            analysisByDay.setRecordDate(new Date());
            analysisByDay.setCreated(new Date());
            analysisByDay.setUpdated(new Date());
            save(analysisByDay);
        }

        //3.查询登陆次数、注册人数、活跃人数、次日保留人数
        //今日注册人数
        Long regNum = logMapper.queryNumsByType(now, "0102");
        //今日登陆次数
        Long loginNum = logMapper.queryNumsByType(now, "0101");
        //今日登陆次数
        Long activeNum = logMapper.queryNumsByDate(now);
        //次日保留人数
        Long retention1dNum = logMapper.queryRetention1d(yesterday, now);

        //4. 把数据封装起来，更新到日表中
        analysisByDay.setNumRegistered(regNum.intValue());
        analysisByDay.setNumLogin(loginNum.intValue());
        analysisByDay.setNumActive(activeNum.intValue());
        analysisByDay.setNumRetention1d(retention1dNum.intValue());
        analysisByDay.setUpdated(new Date());
        updateById(analysisByDay);
    }

    /**
     * 数据统计
     *
     * @param sd
     * @param ed
     * @param type 101 新增 102 活跃用户 103 次日留存率
     * @return
     */

    public ResponseEntity<Object> statistics(Long sd, Long ed, Integer type) {

        //开始时间
        Date sdDate = new Date();
        sdDate.setTime(sd);
        String beginDate = DateUtil.formatDate(sdDate);
        //调用方法获取上一年的开始时间
        String lastBeginDate = getLastDate(sdDate);
        //结束时间
        Date edDate = new Date();
        edDate.setTime(ed);
        String endDate = DateUtil.formatDate(edDate);
        //调用方法获取上一年的结束时间
        String lastEndDate = getLastDate(edDate);
        //查询当前年的数据
        List<AnalysisByDay> thisDate = analysisByDayMapper.findActiveByDate(beginDate, endDate);
        List<SummaryVo> thisYear = null;
        if (thisDate != null) {
            thisYear = getSummaryVo(thisDate, type);
        }
        //查询前一年的数据
        List<AnalysisByDay> lastDate = analysisByDayMapper.findActiveByDate(lastBeginDate, lastEndDate);
        List<SummaryVo> lastYear = null;
        if (lastDate != null) {
            lastYear = getSummaryVo(lastDate, type);
        }
        Map<String, Object> map = new HashMap<>();
        map.put("thisYear", thisYear);
        map.put("lastYear", lastYear);
        return ResponseEntity.ok(map);
    }

    /**
     * 获取上一年时间的工具方法
     */
    public String getLastDate(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        //计算上一年的时间
        c.add(Calendar.YEAR, -1);
        return DateUtil.formatDate(c.getTime());
    }

    /**
     * 获取List<SummaryVo>的工具方法
     */
    public List<SummaryVo> getSummaryVo(List<AnalysisByDay> date, Integer type) {
        List<SummaryVo> summaryVos = new ArrayList<>();
        for (AnalysisByDay analysisByDay : date) {
            SummaryVo summaryVo = new SummaryVo();
            switch (type) {
                case 101://新增
                    summaryVo.setAmount(analysisByDay.getNumRegistered());
                    break;
                case 102: //活跃用户
                    summaryVo.setAmount(analysisByDay.getNumActive());
                    break;
                case 103: //次日留存数
                    summaryVo.setAmount(analysisByDay.getNumRetention1d());
                    break;
            }
            summaryVo.setTitle(new SimpleDateFormat("yyyy-MM-dd").format(analysisByDay.getRecordDate()));
            summaryVos.add(summaryVo);
        }
        return summaryVos;
    }
}
